package com.xuexiang.yoyo.runenable;


import android.os.Build;

import androidx.annotation.RequiresApi;

import java.math.BigDecimal;
import java.time.LocalDateTime;

@RequiresApi(api = Build.VERSION_CODES.O)
public class CreditToken  extends BaseToken {
    private long _amount;        //ORIGINAL LINE: public uint getAmount()
    private BigDecimal _transferAmount = new BigDecimal(0);

    public long get_amount() {
        return this._amount & 0xFFFFFFFFL;
    }

    public void set_amount(long _amount) {
        this._amount = _amount;
//        this._transferAmount = (this.ToTransferAmount(this._amount)) / java.math.BigDecimal.TEN;
        this._transferAmount = BigDecimal.valueOf(this.ToTransferAmount(this._amount) /10 );
    }

    public BigDecimal get_transferAmount() {
        return _transferAmount;
    }


    public void set_transferAmount(BigDecimal value) {
        this._transferAmount = value;
//        this._amount = this.ToAmount((int)(BigDecimal.Round(value, 1).multiply(java.math.BigDecimal.TEN)));
        this._amount = this.ToAmount((value.multiply(BigDecimal.TEN)).longValue());
    }

    public CreditToken() {
    }

    public CreditToken(boolean mode) {
        this.testMode = mode;
    }

    public CreditToken(WorkType wt, boolean mode) {
        super.SetWorkType(wt);
        this.testMode = mode;
    }

    public CreditToken(String inkey) {
        this.TClassNum = 0;
        this.TSubClassNum = 0;
        this.set_transferAmount(new BigDecimal(0));
        this.EToByteTokens();
        this.MakeToken(this.ByteTokens, inkey);
    }

    public CreditToken(long ta, String inkey) {
        this.TClassNum = 0;
        this.TSubClassNum = 0;
        this.set_transferAmount(new BigDecimal(ta));
        this.EToByteTokens();
        this.MakeToken(this.ByteTokens, inkey);
    }


    public CreditToken(long ta, LocalDateTime tid, String inkey) {
        this.TClassNum = 0;
        this.TSubClassNum = 0;
        this.IssueTime = tid;
        this.Tid = super.ToTID(this.IssueTime);
        this.set_transferAmount(new BigDecimal(ta));
        this.EToByteTokens();
        this.MakeToken(this.ByteTokens, inkey);
    }

    public CreditToken(long ta, LocalDateTime tid, byte tsc, String inkey, WorkType wt, boolean mode)
    {
        super.SetWorkType(wt);
        this.testMode = mode;
        this.TClassNum = 0;
        this.TSubClassNum = tsc;
        this.IssueTime = tid;
        this.Tid = super.ToTID(this.IssueTime);
        this.set_transferAmount(new BigDecimal(ta));
        this.EToByteTokens();
        this.MakeToken(this.ByteTokens, inkey);
    }
    public CreditToken(long ta, long tid, byte tsc, String inkey, WorkType wt, boolean mode)
    {
        super.SetWorkType(wt);
        this.testMode = mode;
        this.TClassNum = 0;
        this.TSubClassNum = tsc;
        this.IssueTime = LocalDateTime.now();
        this.Tid = tid;
        this.set_transferAmount(new BigDecimal(ta));
        this.EToByteTokens();
        this.MakeToken(this.ByteTokens, inkey);
    }

    public CreditToken(long ta, LocalDateTime tid, byte rn, byte tsc, String inkey)
    {
        this.TClassNum = 0;
        this.TSubClassNum = tsc;
        this.RandomNum = rn;
        this.IssueTime = tid;
        this.Tid = super.ToTID(this.IssueTime);
        this.set_transferAmount(new BigDecimal(ta));
        this.EToByteTokens();
        this.MakeToken(this.ByteTokens, inkey);
    }

    public CreditToken(long ta, LocalDateTime tid, byte rn, byte tsc, String inkey, boolean mode)
    {
        this.testMode = mode;
        this.TClassNum = 0;
        this.TSubClassNum = tsc;
        this.RandomNum = rn;
        this.IssueTime = tid;
        this.Tid = super.ToTID(this.IssueTime);
        this.set_transferAmount(new BigDecimal(ta));
        this.EToByteTokens();
        this.MakeToken(this.ByteTokens, inkey);
    }

    public CreditToken(long ta, LocalDateTime tid, byte rn, byte tsc, String inkey, WorkType wt, boolean mode)
    {
        super.SetWorkType(wt);
        this.testMode = mode;
        this.TClassNum = 0;
        this.TSubClassNum = tsc;
        this.RandomNum = rn;
        this.IssueTime = tid;
        this.Tid = super.ToTID(this.IssueTime);
        this.set_transferAmount(new BigDecimal(ta));
        this.EToByteTokens();
        this.MakeToken(this.ByteTokens, inkey);
    }

    public CreditToken(long ta, long tid, byte rn, byte tsc, String inkey, WorkType wt, boolean mode)
    {
        super.SetWorkType(wt);
        this.testMode = mode;
        this.TClassNum = 0;
        this.TSubClassNum = tsc;
        this.RandomNum = rn;
        this.IssueTime = LocalDateTime.now();
        this.Tid = tid;
        this.set_transferAmount(new BigDecimal(ta));
        this.EToByteTokens();
        this.MakeToken(this.ByteTokens, inkey);
    }
//---------------------------------------------------------------------------------------------------------------
//ORIGINAL LINE: protected uint ToAmount(uint ta)
    private long ToAmount(long ta)
    {
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
//ORIGINAL LINE: uint taTmp = ta;
        long taTmp = ta;
        if (ta >= 16384 && ta <= 180223)
        {
            taTmp = (ta - 16384) / 10;
            taTmp |= 16384;
        }
        else if (ta >= 180224 && ta <= 1818623)
        {
            taTmp = (ta - 16384 - 163840) / 100;
            taTmp |= 32768;
        }
        else if (ta >= 1818624 && ta <= 18201624)
        {
            taTmp = (ta - 16384 - 163840 - 1638400) / 1000;
            taTmp |= 49152;
        }
        return (taTmp & 0xFFFFFFFFL);
    }

    //ORIGINAL LINE: protected uint ToTransferAmount(uint amount)
    private long ToTransferAmount(long amount)
    {
        //ORIGINAL LINE: uint ttA = 0U;
        long ttA = 0L;
        //ORIGINAL LINE: uint ttC = 1U;
        long ttC = 1L;
        //ORIGINAL LINE: uint e = amount >> 14;
        long e = amount >>> 14;
        //ORIGINAL LINE: uint i = amount & 16383U;
        long i = amount & 16383;
        //ORIGINAL LINE: uint t;
        long t;
        if (e == 0) {
            t = i;
        } else {
            long j = 0;
            //ORIGINAL LINE: while ((long)j < (long)((ulong)e))
            while (j < e) {
                //ORIGINAL LINE: uint ttB = 1U;
                long ttB = 1L;
                for (long k = 0; k < j; k++) {
                    ttB *= 10;
                }
                ttA += ttB;
                j++;
            }
            long l = 0;
            //ORIGINAL LINE: while ((long)l < (long)((ulong)e))
            while (l < e) {
                ttC *= 10;
                l++;
            }
            t = ttA * 16384 + ttC * i;
        }
        return t & 0xFFFFFFFFL;
    }

    //ORIGINAL LINE: public string MakeToken(byte[] source, string inkey)
    public String MakeToken(byte[] source, String inkey)
    {
        return super.EToken(source, inkey);
    }

    @Override
    protected void EToByteTokens()
    {
        this.ByteTokens[0] = this.TClassNum;
        //ORIGINAL LINE: this.ByteTokens[1] = (byte)((int)this.RandomNum + ((int)this.TSubClassNum << 4));
        this.ByteTokens[1] = (byte)((int)this.RandomNum + ((int)this.TSubClassNum << 4));
        //ORIGINAL LINE: this.ByteTokens[2] = (byte)(this.Tid >> 16 & 255U);
        this.ByteTokens[2] = (byte)(this.Tid >> 16 & 255);
        //ORIGINAL LINE: this.ByteTokens[3] = (byte)(this.Tid >> 8 & 255U);
        this.ByteTokens[3] = (byte)(this.Tid >> 8 & 255);
        //ORIGINAL LINE: this.ByteTokens[4] = (byte)(this.Tid & 255U);
        this.ByteTokens[4] = (byte)(this.Tid & 255);
        this._amount = this.ToAmount(this._transferAmount.longValue() & 0xFFFF);
        //ORIGINAL LINE: this.ByteTokens[5] = (byte)(this.Amount >> 8 & 255U);
        this.ByteTokens[5] = (byte)(this._amount >> 8 & 255);
        //ORIGINAL LINE: this.ByteTokens[6] = (byte)(this.Amount & 255U);
        this.ByteTokens[6] = (byte)(this._amount & 255);
    }

    public final boolean DecodeToken(String source, String inkey)
    {
        if (!super.DToken(source, inkey))
        {
            return false;
        }
        this.RandomNum = (byte) (this.ByteTokens[1] & 0x0F);
    //ORIGINAL LINE: this.Tid = (uint)(((int)this.ByteTokens[2] << 16) + ((int)this.ByteTokens[3] << 8) + (int)this.ByteTokens[4]);
        this.Tid = (int)(
                         ((this.ByteTokens[2] & 0xFF) << 16) +
                         ((this.ByteTokens[3] & 0xFF) << 8) +
                         (this.ByteTokens[4] & 0xFF)
                        );
        this.IssueTime = super.TIDToTime((int) this.Tid);
    //ORIGINAL LINE: this.Amount = (uint)(((int)this.ByteTokens[5] << 8) + (int)this.ByteTokens[6]);
        this.set_amount(((this.ByteTokens[5] & 0xFF) << 8) + (this.ByteTokens[6] & 0xFF));
        return true;
    }

}
